#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@file motor_api.py
@brief 电机控制API接口
@details 提供电机控制的Python API接口，供其他程序直接调用
@author zhang33
@date 2025-09-05
"""

import logging
from typing import Optional, Dict, Any, Callable
from enum import Enum

from core.config import ConfigManager
from business import MotorService, ConfigService, MonitoringService

logger = logging.getLogger(__name__)


class ConnectionState(Enum):
    """连接状态枚举"""
    DISCONNECTED = "disconnected"
    CONNECTING = "connecting"
    CONNECTED = "connected"
    ERROR = "error"


class MotorAPI:
    """
    @brief 电机控制API类
    @details 提供电机控制的Python API接口
    """
    
    def __init__(self, config_file: str = "config/serial_config.json"):
        """
        @brief 初始化电机API
        @param config_file 配置文件路径
        """
        self.config_manager = ConfigManager(config_file)
        self.motor_service = MotorService(self.config_manager)
        self.config_service = ConfigService(self.config_manager)
        self.monitoring_service = MonitoringService(self.motor_service, self.config_manager)
        
        # 设置回调函数
        self._setup_callbacks()
        
        logger.info("电机API初始化完成")
    
    def _setup_callbacks(self) -> None:
        """
        @brief 设置回调函数
        """
        self.motor_service.set_connection_callback(self._on_connection_state_changed)
        self.motor_service.set_error_callback(self._on_motor_error)
        self.monitoring_service.set_error_callback(self._on_monitoring_error)
    
    def _on_connection_state_changed(self, state) -> None:
        """
        @brief 连接状态改变回调
        @param state 连接状态
        """
        logger.info(f"连接状态改变: {state.value}")
    
    def _on_motor_error(self, error_msg: str) -> None:
        """
        @brief 电机错误回调
        @param error_msg 错误消息
        """
        logger.error(f"电机错误: {error_msg}")
    
    def _on_monitoring_error(self, error) -> None:
        """
        @brief 监控错误回调
        @param error 错误信息
        """
        logger.error(f"监控错误: {error}")
    
    # ==================== 连接管理 ====================
    
    def connect(self) -> bool:
        """
        @brief 连接到电机驱动器
        @return bool 连接是否成功
        @retval True 连接成功
        @retval False 连接失败
        """
        return self.motor_service.connect()
    
    def disconnect(self) -> None:
        """
        @brief 断开连接
        """
        self.motor_service.disconnect()
    
    def is_connected(self) -> bool:
        """
        @brief 检查是否已连接
        @return bool 是否已连接
        """
        return self.motor_service.is_connected()
    
    def test_connection(self) -> bool:
        """
        @brief 测试连接
        @return bool 连接是否正常
        """
        return self.motor_service.test_connection()
    
    def test_serial_config(self) -> bool:
        """
        @brief 测试串口配置（不建立真实连接）
        @return bool 串口配置是否可用
        """
        return self.motor_service.test_serial_config()
    
    # ==================== 电机控制 ====================
    
    def start_motors(self, left_speed: int = 500, right_speed: int = 500) -> bool:
        """
        @brief 启动电机
        @param left_speed 左电机转速
        @param right_speed 右电机转速
        @return bool 启动是否成功
        """
        return self.motor_service.start_motors(left_speed, right_speed)
    
    def stop_motors(self) -> bool:
        """
        @brief 停止电机
        @return bool 停止是否成功
        """
        return self.motor_service.stop_motors()
    
    def emergency_stop(self) -> bool:
        """
        @brief 急停电机
        @return bool 急停是否成功
        """
        return self.motor_service.emergency_stop()
    
    def set_motor_speed(self, left_speed: Optional[int] = None, 
                       right_speed: Optional[int] = None) -> bool:
        """
        @brief 设置电机转速
        @param left_speed 左电机转速，None表示不设置
        @param right_speed 右电机转速，None表示不设置
        @return bool 设置是否成功
        """
        return self.motor_service.set_motor_speed(left_speed, right_speed)
    
    def phase_learning(self) -> bool:
        """
        @brief 执行相序学习
        @return bool 相序学习是否成功
        """
        return self.motor_service.phase_learning()
    
    def reset_system(self) -> bool:
        """
        @brief 复位系统
        @return bool 复位是否成功
        """
        return self.motor_service.reset_system()
    
    # ==================== 状态监控 ====================
    
    def get_motor_status(self) -> Optional[Dict[str, Any]]:
        """
        @brief 获取电机状态
        @return Optional[Dict[str, Any]] 电机状态信息
        """
        return self.motor_service.get_motor_status()
    
    def start_monitoring(self, callback: Optional[Callable] = None) -> bool:
        """
        @brief 开始状态监控
        @param callback 状态回调函数
        @return bool 启动是否成功
        """
        if callback:
            self.monitoring_service.set_status_callback(callback)
        return self.monitoring_service.start_monitoring()
    
    def stop_monitoring(self) -> None:
        """
        @brief 停止状态监控
        """
        self.monitoring_service.stop_monitoring()
    
    def is_monitoring(self) -> bool:
        """
        @brief 检查是否正在监控
        @return bool 是否正在监控
        """
        return self.monitoring_service.is_monitoring()
    
    # ==================== 数据记录 ====================
    
    def start_logging(self, log_file: str = "motor_data.log") -> bool:
        """
        @brief 开始数据记录
        @param log_file 日志文件路径
        @return bool 启动是否成功
        """
        return self.monitoring_service.start_logging(log_file)
    
    def stop_logging(self) -> None:
        """
        @brief 停止数据记录
        """
        self.monitoring_service.stop_logging()
    
    def is_logging(self) -> bool:
        """
        @brief 检查是否正在记录
        @return bool 是否正在记录
        """
        return self.monitoring_service.is_logging()
    
    # ==================== 配置管理 ====================
    
    def get_serial_config(self) -> Dict[str, Any]:
        """
        @brief 获取串口配置
        @return Dict[str, Any] 串口配置信息
        """
        config = self.config_service.get_serial_config()
        return {
            'port': config.port,
            'baudrate': config.baudrate,
            'device_id': config.device_id,
            'timeout': config.timeout,
            'bytesize': config.bytesize,
            'parity': config.parity,
            'stopbits': config.stopbits
        }
    
    def set_serial_config(self, config: Dict[str, Any]) -> bool:
        """
        @brief 设置串口配置
        @param config 串口配置字典
        @return bool 设置是否成功
        """
        from core.config import SerialConfig
        
        # 只传递SerialConfig支持的参数
        supported_params = {
            'port', 'baudrate', 'device_id', 'timeout', 
            'bytesize', 'parity', 'stopbits'
        }
        filtered_config = {k: v for k, v in config.items() if k in supported_params}
        
        serial_config = SerialConfig(**filtered_config)
        return self.config_service.set_serial_config(serial_config)
    
    def get_motor_config(self) -> Dict[str, Any]:
        """
        @brief 获取电机配置
        @return Dict[str, Any] 电机配置信息
        """
        config = self.config_service.get_motor_config()
        if config is None:
            # 返回空配置，由前端提供默认值
            return {}
        return {
            'left_motor_max_speed': config.left_motor_max_speed,
            'right_motor_max_speed': config.right_motor_max_speed,
            'left_motor_min_speed': config.left_motor_min_speed,
            'right_motor_min_speed': config.right_motor_min_speed,
            'default_speed': config.default_speed,
            'acceleration': config.acceleration,
            'deceleration': config.deceleration,
            'system_mode': config.system_mode
        }
    
    def send_serial_command(self, command: str) -> str:
        """
        @brief 发送串口命令
        @param command 要发送的命令
        @return str 发送结果
        """
        return self.motor_service.send_serial_command(command)
    
    def receive_serial_data(self) -> str:
        """
        @brief 接收串口数据
        @return str 接收到的数据
        """
        return self.motor_service.receive_serial_data()
    
    def start_serial_terminal(self) -> bool:
        """
        @brief 启动串口终端
        @return bool 启动是否成功
        """
        return self.motor_service.start_serial_terminal()
    
    def stop_serial_terminal(self) -> bool:
        """
        @brief 停止串口终端
        @return bool 停止是否成功
        """
        return self.motor_service.stop_serial_terminal()
    
    def set_motor_config(self, config: Dict[str, Any]) -> bool:
        """
        @brief 设置电机配置
        @param config 电机配置字典
        @return bool 设置是否成功
        """
        from core.config import MotorConfig
        motor_config = MotorConfig(**config)
        return self.config_service.set_motor_config(motor_config)
    
    def save_config(self) -> bool:
        """
        @brief 保存配置到文件
        @return bool 保存是否成功
        """
        return self.config_service.save_config()
    
    def load_config(self) -> bool:
        """
        @brief 从文件加载配置
        @return bool 加载是否成功
        """
        return self.config_service.load_config()
    
    # ==================== 便捷方法 ====================
    
    def move_forward(self, speed: int = 500) -> bool:
        """
        @brief 前进
        @param speed 转速
        @return bool 操作是否成功
        """
        return self.set_motor_speed(speed, speed)
    
    def move_backward(self, speed: int = 500) -> bool:
        """
        @brief 后退
        @param speed 转速
        @return bool 操作是否成功
        """
        return self.set_motor_speed(-speed, -speed)
    
    def turn_left(self, speed: int = 500) -> bool:
        """
        @brief 左转
        @param speed 转速
        @return bool 操作是否成功
        """
        return self.set_motor_speed(-speed, speed)
    
    def turn_right(self, speed: int = 500) -> bool:
        """
        @brief 右转
        @param speed 转速
        @return bool 操作是否成功
        """
        return self.set_motor_speed(speed, -speed)
    
    def differential_move(self, left_speed: int, right_speed: int) -> bool:
        """
        @brief 差速移动
        @param left_speed 左电机转速
        @param right_speed 右电机转速
        @return bool 操作是否成功
        """
        return self.set_motor_speed(left_speed, right_speed)
    
    # ==================== 上下文管理器 ====================
    
    def __enter__(self):
        """
        @brief 上下文管理器入口
        @return self 返回自身实例
        """
        self.connect()
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        @brief 上下文管理器出口
        @param exc_type 异常类型
        @param exc_val 异常值
        @param exc_tb 异常追踪
        """
        self.disconnect()
    
    # ==================== UART串口日志监控相关方法 ====================
    
    def connect_uart(self) -> bool:
        """
        @brief 连接UART串口用于日志监控
        @return bool 连接是否成功
        """
        return self.motor_service.connect_uart()
    
    def disconnect_uart(self) -> bool:
        """
        @brief 断开UART串口连接
        @return bool 断开是否成功
        """
        return self.motor_service.disconnect_uart()
    
    def is_uart_connected(self) -> bool:
        """
        @brief 检查UART连接状态
        @return bool 是否已连接
        """
        return self.motor_service.is_uart_connected()
    
    def send_uart_command(self, command: str) -> str:
        """
        @brief 发送UART命令
        @param command 要发送的命令
        @return str 发送结果
        """
        return self.motor_service.send_uart_command(command)
    
    def receive_uart_data(self) -> str:
        """
        @brief 接收UART数据
        @return str 接收到的数据
        """
        return self.motor_service.receive_uart_data()
    
    def start_uart_monitor(self) -> bool:
        """
        @brief 启动UART监控
        @return bool 启动是否成功
        """
        return self.motor_service.start_uart_monitor()
    
    def stop_uart_monitor(self) -> bool:
        """
        @brief 停止UART监控
        @return bool 停止是否成功
        """
        return self.motor_service.stop_uart_monitor()
    
    def get_uart_config(self) -> Dict[str, Any]:
        """
        @brief 获取UART配置
        @return Dict[str, Any] UART配置字典
        """
        try:
            uart_config = self.config_manager.get_uart_config()
            return {
                'port': uart_config.port,
                'baudrate': uart_config.baudrate,
                'timeout': uart_config.timeout,
                'bytesize': uart_config.bytesize,
                'parity': uart_config.parity,
                'stopbits': uart_config.stopbits
            }
        except Exception as e:
            logger.error(f"获取UART配置异常: {e}")
            return {}
    
    def set_uart_config(self, config: Dict[str, Any]) -> bool:
        """
        @brief 设置UART配置
        @param config UART配置字典
        @return bool 设置是否成功
        """
        try:
            from core.config import UARTConfig
            
            # 过滤支持的参数
            supported_params = ['port', 'baudrate', 'timeout', 'bytesize', 'parity', 'stopbits']
            filtered_config = {k: v for k, v in config.items() if k in supported_params}
            
            uart_config = UARTConfig(**filtered_config)
            self.config_manager.set_uart_config(uart_config)
            return True
        except Exception as e:
            logger.error(f"设置UART配置异常: {e}")
            return False
    
    def test_uart_config(self) -> Dict[str, Any]:
        """
        @brief 测试UART配置
        @return Dict[str, Any] 测试结果
        """
        try:
            uart_config = self.config_manager.get_uart_config()
            
            # 创建临时UART驱动进行测试
            from drivers.uart_driver import UARTDriver
            temp_driver = UARTDriver(
                port=uart_config.port,
                baudrate=uart_config.baudrate,
                timeout=uart_config.timeout,
                bytesize=uart_config.bytesize,
                parity=uart_config.parity,
                stopbits=uart_config.stopbits
            )
            
            # 尝试连接
            if temp_driver.connect():
                temp_driver.disconnect()
                return {
                    'success': True,
                    'message': f'UART串口 {uart_config.port} 连接测试成功',
                    'port': uart_config.port,
                    'baudrate': uart_config.baudrate
                }
            else:
                return {
                    'success': False,
                    'message': f'UART串口 {uart_config.port} 连接测试失败',
                    'port': uart_config.port,
                    'baudrate': uart_config.baudrate
                }
                
        except Exception as e:
            logger.error(f"测试UART配置异常: {e}")
            return {
                'success': False,
                'message': f'UART配置测试异常: {e}',
                'port': config.get('port', 'unknown'),
                'baudrate': config.get('baudrate', 'unknown')
            }
